package de.lulusoft.anothertorrent.gui.commands;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.HandlerEvent;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.IHandlerListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.handlers.HandlerUtil;

import de.lulusoft.anothertorrent.core.rtorrent.TorrentCommand;
import de.lulusoft.anothertorrent.core.rtorrent.TorrentCommands;
import de.lulusoft.anothertorrent.core.servers.Server;
import de.lulusoft.anothertorrent.gui.AnotherTorrentGui;
import de.lulusoft.anothertorrent.gui.exceptions.ExceptionHandler;
import de.lulusoft.anothertorrent.gui.preferences.PreferenceConstants;
import de.lulusoft.anothertorrent.gui.views.ServerView;

public class AddTorrentByFileCommand implements IHandler, PropertyChangeListener {
	
	public static final String ID = "de.lulusoft.anothertorrent.gui.commands.AddTorrentByFileCommand";

	private ArrayList<IHandlerListener> listeners = new ArrayList<IHandlerListener>();
	private boolean registeredWithServerView = false;
	private ServerView serverView = null;
	
	@Override
	public void addHandlerListener(IHandlerListener handlerListener) {
		listeners.add(handlerListener);
	}

	@Override
	public void dispose() {
		
	}

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		System.out.println("AddTorrentByFileCommand");
		
		FileDialog fd = new FileDialog(Display.getDefault().getActiveShell());
		fd.setFilterExtensions(new String[]{"*.torrent", "*.*"});
		fd.setFilterIndex(0);
		fd.setFilterNames(new String[]{"Torrent Files", "All Files"});
		fd.setText("Select a Torrent");
		
		String filename = fd.open();
		if (filename != null)
		{
			File torrent = new File(filename);
			if (serverView  != null
					&& !serverView.getViewerSelection().isEmpty()
					&& serverView.getViewerSelection().getFirstElement() instanceof Server)
			{
				Server server = (Server)serverView.getViewerSelection().getFirstElement();
				try {
					// Get optional torrent commands
					ElementListSelectionDialog select = new ElementListSelectionDialog(HandlerUtil.getActiveShell(event), new ILabelProvider() {
					
						@Override
						public void removeListener(ILabelProviderListener listener) {}
						@Override
						public boolean isLabelProperty(Object element, String property) {
							return false;
						}
						@Override
						public void dispose() {}
						@Override
						public void addListener(ILabelProviderListener listener) {}
						@Override
						public String getText(Object element) {
							return ((TorrentCommand)element).getName();
						}
						@Override
						public Image getImage(Object element) {
							return null;
						}
					});
					select.setMultipleSelection(false);
					select.setMessage("Choose the command to execute on the new torrent");
					select.setTitle("Choose Torrent Auto Command");
					select.setElements(TorrentCommands.getINSTANCE().getCommands().toArray());
					if (select.open() == ElementListSelectionDialog.OK)
					{
						TorrentCommand tc = (TorrentCommand)select.getFirstResult();
						if (AnotherTorrentGui.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.P_START_ADDED_TORRENTS))
							server.getRTorrentManager().torrentAddByFileAndStartWithParams(torrent, tc);
						else
							server.getRTorrentManager().torrentAddByFileDontStartWithParams(torrent, tc);
					}
					else {
						if (AnotherTorrentGui.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.P_START_ADDED_TORRENTS))
							server.getRTorrentManager().torrentAddByFileAndStart(torrent);
						else
							server.getRTorrentManager().torrentAddByFileDontStart(torrent);
					}	
				} catch (Exception e) {
					ExceptionHandler.alert("Could not add torrent.", e);
				}				
			}
		}
		
		return null;
	}

	@Override
	public boolean isEnabled() {
		try 
		{
			if (serverView == null)
				serverView = (ServerView)PlatformUI.getWorkbench()
					.getActiveWorkbenchWindow().getActivePage().findView(ServerView.ID);
			if (!registeredWithServerView && serverView != null)
			{
				serverView.addPropertyChangeListener(this);
				registeredWithServerView = true;
			}
			
			if (serverView != null
					&& !serverView.getViewerSelection().isEmpty()
					&& serverView.getViewerSelection().getFirstElement()
					instanceof Server)
				return true;
		}catch (NullPointerException ne) {
			// ignore silently
		} 
		catch (Exception e) {
			ExceptionHandler.handle(e);
		}
		return false;
	}

	@Override
	public boolean isHandled() {
		return true;
	}

	@Override
	public void removeHandlerListener(IHandlerListener handlerListener) {
		listeners.remove(handlerListener);
	}

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		if (evt.getSource() instanceof ServerView
				&& evt.getPropertyName().equals(ServerView.P_SERVER))
		{
			for (IHandlerListener listener : listeners)
			{
				HandlerEvent handlerEvent = new HandlerEvent(this, true, false);
				listener.handlerChanged(handlerEvent );
			}
		}
	}

}
